﻿using Core.Utility.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{
    /// <summary>
    /// 随机助手类
    /// </summary>
    public static class RandomHelper
    {

        #region 生成纯随机数字
        /// <summary>
        /// 生成纯随机数字
        /// </summary>
        /// <param name="length">字符长度</param>
        /// <returns>纯随机数字</returns>
        public static string OnlyNum(int length)
        {
            return Chars(length, RandomCharType.Num, false);
        }

        #endregion

        #region 生成随机字母与数字结合
        /// <summary>
        /// 生成随机字母与数字结合
        /// </summary>
        /// <param name="Length">字符长度</param>
        /// <param name="type">字母大小写类型</param>
        /// <returns>字母与数字结合的字符串</returns>
        public static string NumChar(int Length, RandomCharCaseType type = RandomCharCaseType.UpperAndLower)
        {
            string str = Chars(Length, RandomCharType.NumChar, false);
            return CaseConvert(str, type);
        }
        #endregion

        #region 生成纯随机字母
        /// <summary>
        /// 生成纯随机字母
        /// </summary>
        /// <param name="Length">字符长度</param>
        /// <param name="type">字母大小写类型</param>
        /// <returns>纯随机字母</returns>
        public static string OnlyChar(int Length, RandomCharCaseType type)
        {
            string str = Chars(Length, RandomCharType.Char, false);
            return CaseConvert(str, type);
        }
        #endregion

        #region 生成随机字符
        /// <summary>
        /// 生成随机字符
        /// </summary>
        /// <param name="length">字符长度</param>
        /// <param name="isSleep">是否要在生成前将当前线程阻止以避免重复</param>
        /// <param name="charType">字符类型</param>
        /// <returns>随机字符组成的字符串</returns>
        public static string Chars(int length, RandomCharType charType = RandomCharType.NumChar, bool isSleep = false)
        {
            if (isSleep) System.Threading.Thread.Sleep(3);
            int minValue = 0;
            int maxValue = 0;
            char[] chars = new char[] 
            { 
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
                'U', 'V', 'W', 'X', 'Y', 'Z'
            };
            switch (charType)
            {
                case RandomCharType.Num:
                    minValue = 0;
                    maxValue = 10;
                    break;
                case RandomCharType.Char:
                    minValue = 11;
                    maxValue = 36;
                    break;
                case RandomCharType.NumChar:
                    minValue = 0;
                    maxValue = 36;
                    break;
                default:
                    break;
            }
            string result = "";
            Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
            for (int i = 0; i < length; i++)
            {
                int rnd = random.Next(minValue, maxValue);
                result += chars[rnd];
            }
            return result;
        }
        #endregion

        #region 字母大小写转换
        /// <summary>
        /// 字母大小写转换
        /// </summary>
        /// <param name="chars">需要转换的字符串</param>
        /// <param name="type">字母大小写类型</param>
        /// <returns>转换后的字符串</returns>
        private static string CaseConvert(string chars, RandomCharCaseType type)
        {
            string result = string.Empty;
            switch (type)
            {
                case RandomCharCaseType.Upper:
                    result = chars.ToUpper();
                    break;
                case RandomCharCaseType.Lower:
                    result = chars.ToLower();
                    break;
                case RandomCharCaseType.UpperAndLower:
                    StringBuilder tempStr = new StringBuilder();
                    Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
                    for (int i = 0; i < chars.Length; i++)
                    {
                        string str = chars.Substring(i, 1);
                        tempStr.Append(random.Next(2) == 1 ? str.ToUpper() : str.ToLower());
                    }
                    result = tempStr.ToString();
                    break;
                default:
                    break;
            }
            return result;
        }
        #endregion
    }


    /// <summary>
    /// 随机字符类型
    /// </summary>
    public enum RandomCharType
    {
        /// <summary>
        /// 纯数字
        /// </summary>
        [CodeValueDescription(order: 1, code: "Num", value: "1", description: "纯数字")]
        Num = 1,

        /// <summary>
        /// 纯字母
        /// </summary>
        [CodeValueDescription(order: 2, code: "Char", value: "2", description: "纯字母")]
        Char = 2,

        /// <summary>
        /// 数字和字母结合
        /// </summary>
        [CodeValueDescription(order: 3, code: "NumChar", value: "3", description: "数字和字母")]
        NumChar = 3
    }

    /// <summary>
    /// 字母大小写类型
    /// </summary>
    public enum RandomCharCaseType
    {
        /// <summary>
        /// 大写
        /// </summary>
        [CodeValueDescription(order: 1, code: "Upper", value: "1", description: "大写")] 
        Upper = 1,

        /// <summary>
        /// 小写
        /// </summary>
        [CodeValueDescription(order: 2, code: "Lower", value: "2", description: "小写")]        
        Lower = 2,

        /// <summary>
        /// 混合
        /// </summary>
        [CodeValueDescription(order: 3, code: "Mix", value: "3", description: "大小写混合")]
        UpperAndLower = 3
    }

}
